﻿using System;
using System.Web.Mvc;
using EnetaMvc.ApplicationServices;
using EnetaMvc.ApplicationServices.Dto;
using EnetaMvc.Web.Attributes;
using EnetaMvc.Web.Extensions;
using EnetaMvc.Web.Models;

namespace EnetaMvc.Web.Controllers
{
    public class ArticlesController : BaseController
    {
        private readonly IContentService _contentService;
        private readonly INewsService _newsService;
        private readonly IUserService _userService;

        public ArticlesController(IContentService contentService, INewsService newsService, IUserService userService)
        {
            _contentService = contentService;
            _newsService = newsService;
            _userService = userService;
        }

        [HttpGet]
        public ActionResult Index(int page = 1)
        {
            if (page < 1)
                page = 1;

            var result = _newsService.ListPublishedArticles(page, 10);

            return View(result);
        }

        [HttpGet]
        public ActionResult Details(long id)
        {
            var article = _newsService.GetArticleById(id);
            if (article == null)
                return HttpNotFound("Cannot find blog with ID " + id);

            var model = new ArticleDetailsModel();
            model.Article = article;

            return View(model);
        }

        [HttpPost]
        [EnetaAuthorize(Roles = "User, Administrator")]
        public ActionResult AddComment(long id, string body)
        {
            var user = _userService.GetUserByToken(User.Identity.Name);
            var comment = new CommentDto();
            comment.ContentItemId = id;
            comment.Created = DateTime.Now;
            comment.AuthorId = user.Id;
            comment.Body = body;

            _contentService.SaveComment(comment);

            return RedirectToAction("Details", new { id = id });
        }

        [HttpGet]
        [EnetaAuthorize(Roles = "User, Administrator")]
        public ActionResult Create()
        {
            var model = new ArticleEditModel();

            return View("Edit", model);
        }

        [HttpPost]
        [EnetaAuthorize(Roles = "User, Administrator")]
        [ValidateInput(false)]
        public ActionResult Create(ArticleEditModel model)
        {
            if (!ModelState.IsValid)
            {
                FillArticleEditModel(model);
                return View("Edit", model);
            }

            SaveArticle(model);

            return RedirectToAction("Index");
        }        

        [HttpGet]
        [EnetaAuthorize(Roles = "User, Administrator")]
        public ActionResult Edit(long id)
        {
            var article = _newsService.GetArticleById(id);
            if (article == null)
                return HttpNotFound("Cannot find blog with ID " + id);

            var user = _userService.GetUserByToken(User.Identity.Name);

            if (!User.IsInRole("Administrator"))
                if (article.CreatedById != user.Id)
                    return new HttpStatusCodeResult(403, "Cannot access requested resource");

            var model = new ArticleEditModel();
            model.Article = article;
            FillArticleEditModel(model);

            return View(model);
        }

        [HttpPost]
        [EnetaAuthorize(Roles = "User, Administrator")]
        [ValidateInput(false)]
        public ActionResult Edit(ArticleEditModel model)
        {
            if (!ModelState.IsValid)
            {
                FillArticleEditModel(model);
                return View(model);
            }

            SaveArticle(model);

            return RedirectToAction("Index");
        }

        [EnetaAuthorize(Roles = "Administrator")]
        public ActionResult ContentAction(long id, string actionName, long[] tags, string comment = "")
        {
            if (actionName == Resources.EnetaMvc.Edit)
            {
                return RedirectToAction("Edit", new { id = id });
            }

            var user = _userService.GetUserByToken(User.Identity.Name);
            var article = _newsService.GetArticleById(id);
            article.SaveTagIds = tags;

            if (actionName == Resources.EnetaMvc.Approve)
            {
                if (article.PublishStateId != 1)
                {
                    article.PublishStateId = 1;
                    article.PublishStateById = user.Id;
                    article.PublishStateDate = DateTime.Now;
                    _contentService.SaveContentItemSlagLog(article.Id, article.PublishStateId, article.PublishStateById);
                }
            }
            if (actionName == Resources.EnetaMvc.Reject)
            {
                if (article.PublishStateId != 3)
                {
                    article.PublishStateId = 3;
                    article.PublishStateById = user.Id;
                    article.PublishStateDate = DateTime.Now;
                    article.PublishComment = comment;
                    _contentService.SaveContentItemSlagLog(article.Id, article.PublishStateId, article.PublishStateById);
                }
            }
            _newsService.SaveArticle(article);

            return RedirectToAction("Details", new { id = id });
        }

        [NonAction]
        private void FillArticleEditModel(ArticleEditModel model)
        { 
            var selectedPublishState = 1L;
            if(model.Article != null)
            {
                selectedPublishState = model.Article.PublishStateId;
            }

            model.PublishStates = _contentService.ListPublishStates().ToSelectList(selectedPublishState);
        }

        [NonAction]
        private void SaveArticle(ArticleEditModel model)
        {
            var user = _userService.GetUserByToken(User.Identity.Name);

            if (model.Article.Id == 0)
            {
                model.Article.Created = DateTime.Now;
                model.Article.CreatedById = user.Id;
                model.Article.PublishStateById = user.Id;
                model.Article.PublishStateDate = DateTime.Now;
                model.Article.PublishStateId = 1;
            }
            else if (!User.IsInRole("Administrator"))
            {
                var originalArticle = _newsService.GetArticleById(model.Article.Id);
                if (originalArticle.PublishStateId == 3)
                {
                    model.Article.PublishStateId = 2;
                    model.Article.PublishStateDate = DateTime.Now;
                    model.Article.PublishStateById = user.Id;
                }
                else
                {
                    model.Article.PublishStateDate = originalArticle.PublishStateDate;
                    model.Article.PublishStateId = originalArticle.PublishStateId;
                    model.Article.PublishComment = originalArticle.PublishComment; 
                    model.Article.PublishStateById = originalArticle.PublishStateById;
                }
            }
            else
            {
                var originalArticle = _newsService.GetArticleById(model.Article.Id);
                model.Article.Created = originalArticle.Created;
                model.Article.PublishStateDate = originalArticle.PublishStateDate;

                if (originalArticle.PublishStateId != model.Article.PublishStateId)
                {
                    model.Article.PublishStateById = user.Id;
                    model.Article.PublishStateDate = DateTime.Now;
                }
            }
            _newsService.SaveArticle(model.Article);
        }
    }
}